/*************************************************************************************
*
*	This Component Class provides one JTextArea capable to capture 
*	and display the System output and System err, any contanct and
* 	question to acortiz@ucsm.edu.pe
*
*	Based in Java Developer Connection(sm) (JDC) Tech Tips, 
*	October 21, 1999. Wrote by Patrick Chan. 
*	Topic called "Capturing Standard Output in a Log File"
*
*	Class 		: JOutputArea.java
*	Version		: 1.0 22 Jun 2003
*	Author 		: Alan Ortiz Mej�a
*	Date		: 22/06/2003
*
*************************************************************************************/
package Sindarin;

import javax.swing.*;
import java.io.*;

/**
* This Component Class provides one JTextArea capable to capture 
* and display the System output and System err
*
* Based in Java Developer Connection(sm) (JDC) Tech Tips, 
* October 21, 1999. Wrote by Patrick Chan. 
* Topic called "Capturing Standard Output in a Log File"
*
* @version	: 1.0 22 Jun 2003
* @author 	: Alan Ortiz Mej�a
*/

public class JOutputArea extends JTextArea
{
	private OutputAreaStream out;
		
	/**
	* Defines a JOutputArea that captures the output and err streams
	* with the default show options
	*/
	public JOutputArea()
	{
		super("JOutputArea 1.0\nAlan Ortiz Mej�a 2003\nQuestions to: acortiz@ucsm.edu.pe\n");
		out = new OutputAreaStream(System.out, this);
		setEditable(false);
	}

	/**
	* Defines a JOutputArea with the specified show options
	*/
	public JOutputArea(boolean sOut, boolean sErr, boolean mirror){
		this();
		out.showOut(sOut);
		out.showErr(sErr);
		out.mirror = mirror;		
	}

	/**
	* Specifies if this component shows the stream(s) also in console
	*/
	public void setMirror(boolean b)
	{
		out.mirror = b;
	}

	/**
	* Sets if the JOutputArea shows the output stream
	*/
	public void showOut(boolean b)
	{
		out.showOut(b);
	}
	
	/**
	* Sets if the JOutputArea shows the err stream
	*/
	public void showErr(boolean b)
	{
		out.showErr(b);
	}

	private class OutputAreaStream extends PrintStream
	{
		PrintStream oldStdout;
	    PrintStream oldStderr;
		JTextArea out;
		boolean mirror = false;

		// constructor
		public OutputAreaStream(PrintStream ps, JOutputArea outArea) {
			super(ps);
			oldStdout = System.out;
			oldStderr = System.err;
			out = outArea;
			System.setOut(this);
			System.setErr(this);
	    }

		// show output?
	    public void showOut(boolean b)
	    {
	    	if (b){
	    		System.setOut(this);
	    	}else{
	    		System.setOut(oldStdout);
	    	}
	    }
	    
		// show err?
	    public void showErr(boolean b)
	    {
	    	if (b){
	    		System.setErr(this);
	    	}else{
	    		System.setErr(oldStderr);
	    	}
	    }

            //Finalizes the component
	    public void finalize() {
			System.setOut(oldStdout);
			System.setErr(oldStderr);
	        try {

	        } catch (Exception e) {
	            e.printStackTrace();
	        }
	    }

	    // PrintStream override.
	    public void write(int b) {
	        try {
			out.append(Integer.toString(b));
	        } catch (Exception e) {
	            e.printStackTrace();
	            setError();
	        }
	        if (mirror)	{
	        	super.write(b);
	        }
	    }
	    // PrintStream override.
	    public void write(byte buf[], int off, int len) {
	        try {
				out.append(new String(buf, off, len));
			} catch (Exception e) {
				e.printStackTrace();
				setError();
			}
			if (mirror)	{
				super.write(buf, off, len);
			}
		}
	}
}